//Wrapper for EE::PhysicsClass
#pragma once
#include "stdafx.h"

namespace EsenthelNet
{
	///<summary>Handling the character controller slope sliding issue</summary>
	public enum class ControllerSlopeSlidingMode {
		///<summary>Nothing is done in this case</summary>
		CSS_NONE     ,
		///<summary>Character Controllers will switch  their actor's material depending wheter the character is moving or standing between PHYS_MTRL_CHR  and PHYS_MTRL_CHR_STOP, which have different frictions</summary>
		CSS_MATERIALS,
		///<summary>Character Controllers will disable their gravity when standing still on ground, not recommended when character's weight should affect objects underneath</summary>
		CSS_GRAVITY  , 
		///<summary>Character Controllers will disable their xz movement when standing still on ground, not recommended when character's need to be pushed</summary>
		CSS_FREEZE_XZ,
	};

	///<summary>Indexes of Physics Materials, values 0..127 are used by the engine (but can be modified), indexes 128..255 can be used freely</summary>
	public enum class PhysMaterial {
		///<summary>Default material for all actors</summary>
		PHYS_MTRL_ROCK      ,
		PHYS_MTRL_GRASS     ,
		PHYS_MTRL_ICE       ,
		PHYS_MTRL_MUD       ,
		///<summary>Used for character controllers </summary>
		PHYS_MTRL_CHR       , 
		///<summary>Used for character controllers while not moving, this has greater friction values to disable character sliding from slopes, used in CSS_MATERIALS mode</summary>
		PHYS_MTRL_CHR_STOP  , 
		///<summary>From here you should specify custom materials</summary>
		PHYS_MTRL_CUSTOM=128, 
		///<summary>Maximum number of physics materials</summary>
		PHYS_MTRL_NUM   =256,
	};

	///<summary>Physics timestep updating modes</summary>
	public enum class PhysTimestepMode {
		///<summary>Physics timesteps will be rounded to a constant value, this results in more stable and reproducible simulation, this mode is encouraged for vehicle simulation</summary>
		PHYS_TIMESTEP_ROUND   ,  
		///<summary>Physics timesteps are taken from frame time deltas, this results in more smooth but less stable  simulation</summary>
		PHYS_TIMESTEP_VARIABLE, 
		///<summary>Number of physics timestep modes</summary>
		PHYS_TIMESTEP_NUM     , 
	};

	public ref struct PhysMtrl {
		//ToDo
	};

	public ref struct PhysHit {
		//ToDo
	};

	public ref class PhysicsClass {
	public:
		
		///<summary>Create, 'hardware'=if use hardware physics simulations (on GPU/PPU), if it's not available or 'hardware' is set to false then CPU will be used, Exit on fail</summary>
		EsenthelNet::PhysicsClass^ Create() { Physics.create(); return this; }
		///<summary>Create, 'hardware'=if use hardware physics simulations (on GPU/PPU), if it's not available or 'hardware' is set to false then CPU will be used, Exit on fail</summary>
		EsenthelNet::PhysicsClass^ Create(EsenthelNet::ControllerSlopeSlidingMode css) { Physics.create((CONTROLLER_SLOPE_SLIDING_MODE)css); return this; }
		///<summary>Create, 'hardware'=if use hardware physics simulations (on GPU/PPU), if it's not available or 'hardware' is set to false then CPU will be used, Exit on fail</summary>
		EsenthelNet::PhysicsClass^ Create(EsenthelNet::ControllerSlopeSlidingMode css, bool hardware) { Physics.create((CONTROLLER_SLOPE_SLIDING_MODE)css, hardware); return this; }

		///<summary>Create, 'hardware'=if use hardware physics simulations (on GPU/PPU), if it's not available or 'hardware' is set to false then CPU will be used, false on fail</summary>
		bool CreateTry() { return Physics.createTry(); }
		///<summary>Create, 'hardware'=if use hardware physics simulations (on GPU/PPU), if it's not available or 'hardware' is set to false then CPU will be used, false on fail</summary>
		bool CreateTry(EsenthelNet::ControllerSlopeSlidingMode css) { return Physics.createTry((CONTROLLER_SLOPE_SLIDING_MODE)css); }
		///<summary>Create, 'hardware'=if use hardware physics simulations (on GPU/PPU), if it's not available or 'hardware' is set to false then CPU will be used, false on fail</summary>
		bool CreateTry(EsenthelNet::ControllerSlopeSlidingMode css, bool hardware) { return Physics.createTry((CONTROLLER_SLOPE_SLIDING_MODE)css, hardware); }

		///<summary>If physics has been created</summary>
		PropMetGet(bool, Created, Physics.created)
		///<summary>If physics has been updated this frame(this value is valid after 'Physics.get')</summary>
		PropMetGet(bool, Updated, Physics.updated)
		///<summary>Get physics time which has been updated this frame (this value is valid after 'Physics.get')</summary>
		PropMetGet(float, UpdatedTime, Physics.updatedTime)
		///<summary>If physics is simulated in the hardware</summary>
		PropMetGet(bool, Hardware, Physics.hw)

		///<summary>Set/get continous collision detection, default=true</summary>
		PropMet(bool, CCD, Physics.ccd)
		///<summary>Set/get physics skin width (allowed object interpenetration), default=0.005</summary>
		PropMet(float, Skin, Physics.skin)
		///<summary>Set/get gravity acceleration</summary>
		PropMetVecP(Gravity, Physics.gravity)
		///<summary>Set/get number of calculations per second, default=60, setting precision to zero forces usage of screen refresh rate</summary>
		PropMet(int, Precision, Physics.precision)
		///<summary>Set/get physics time stepping mode, default=PHYS_TIMESTEP_ROUNDe</summary>
		PropMetTarget(EsenthelNet::PhysTimestepMode, Timestep, Physics.timestep, PHYS_TIMESTEP_MODE)
	};

}